/*
* 文件：ConfigUI.cs
* 作者：王阳
* 时间：2024-5-20
* 描述：ConfigUI
*/
using CSharpX;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace UnityX
{
    public class ConfigUI : MonoBehaviour
    {
        public class FocusedHandler : MonoBehaviour, ISelectHandler, IDeselectHandler
        {
            public void OnSelect(BaseEventData eventData)
            {
                transform.parent.GetComponent<RawImage>().color = new Color(0, 0.6f, 0.8f, 0.8f);
            }
            public void OnDeselect(BaseEventData eventData)
            {
                transform.parent.GetComponent<RawImage>().color = Color.clear;
            }
        }

        private Color m_WindowBackgroundColor = new Color(0, 0.2f, 0.2f, 0.8f);
        private Color m_BarBackgroundColor = new Color(0, 0.3f, 0.3f, 0.8f);
        private Color m_ButtonBackgroundColor = new Color(0, 0.4f, 0.5f, 0.8f);
        private Color m_ScrollbarBackgroundColor = new Color(0, 0.2f, 0.25f, 0.8f);
        private Color m_ScrollbarForegroundColor = new Color(0, 0.4f, 0.5f, 0.8f);
        private Color m_TextColor = Color.white;

        private GameObject m_WindowGO;
        private GameObject m_TopBarGO;
        private GameObject m_ContentBarGO;
        private GameObject m_ContentGO;

        private GameObject m_FileListButtonGO;
        private GameObject m_LineListButtonGO;
        private ScrollRect m_ContentScrollRect;
        private Text m_TitleText;

        private Font m_Font;
        private int m_FontSize = 20;

        private ConfigFile m_CurrentConfigFile;

        private List<GameObject> m_ItemGameObjects = new List<GameObject>();

#if UNITY_EDITOR
        private static string lastSaveDirectory = null;
#endif

        public static void Open()
        {
            if (GameObject.Find("_ConfigUI_") != null) return;
            new GameObject("_ConfigUI_").AddComponent<ConfigUI>();
        }
        public static void Close()
        {
            if (GameObject.Find("_ConfigUI_") == null) return;
            Destroy(GameObject.Find("_ConfigUI_"));
        }

        void Awake()
        {
#if UNITY_2022_3_OR_NEWER
            m_Font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
#else
            m_Font = Resources.GetBuiltinResource<Font>("Arial.ttf");
#endif
            m_FontSize = 16 + (int)Curve.L1(0, 12, 100, 500, Screen.dpi) + (int)Curve.L1(0, 24, 1000, 5000, Screen.width < Screen.height ? Screen.width : Screen.height);
            m_FontSize = m_FontSize & 0xFFFE;

            //检测程序是否添加事件系统
            if (EventSystem.current == null)
            {
                GameObject es = new GameObject("EventSystem");
                es.AddComponent<EventSystem>();
                es.AddComponent<StandaloneInputModule>();
            }

            //创建界面
            DontDestroyOnLoad(gameObject);
            gameObject.hideFlags = HideFlags.HideInHierarchy;
            Canvas canvas = gameObject.AddComponent<Canvas>();
            canvas.renderMode = RenderMode.ScreenSpaceOverlay;
            canvas.sortingOrder = 32764;
            gameObject.AddComponent<GraphicRaycaster>();

            m_WindowGO = new GameObject("_ConfigWindows_", typeof(CanvasRenderer), typeof(RawImage));
            m_WindowGO.transform.SetParent(transform, false);
            m_WindowGO.GetComponent<RawImage>().color = m_WindowBackgroundColor;
            RectTransform rectTransform = m_WindowGO.transform as RectTransform;
            rectTransform.anchorMin = Vector2.zero;
            rectTransform.anchorMax = Vector2.one;
            rectTransform.offsetMin = Vector2.zero;
            rectTransform.offsetMax = Vector2.zero;

            //上栏
            {
                m_TopBarGO = new GameObject("_TopBar_", typeof(CanvasRenderer), typeof(RawImage));
                m_TopBarGO.transform.SetParent(m_WindowGO.transform, false);
                m_TopBarGO.GetComponent<RawImage>().color = m_BarBackgroundColor;
                rectTransform = m_TopBarGO.transform as RectTransform;
                rectTransform.anchorMin = new Vector2(0, 1);
                rectTransform.anchorMax = new Vector2(1, 1);
                rectTransform.offsetMin = new Vector2(m_FontSize / 2, -((m_FontSize / 2) + (m_FontSize * 2)));
                rectTransform.offsetMax = new Vector2(-(m_FontSize / 2), -(m_FontSize / 2));

                GameObject titleTextGo = new GameObject("_TitleText_", typeof(CanvasRenderer), typeof(Text));
                titleTextGo.transform.SetParent(m_TopBarGO.transform, false);
                rectTransform = titleTextGo.transform as RectTransform;
                rectTransform.anchorMin = Vector2.zero;
                rectTransform.anchorMax = Vector2.one;
                rectTransform.offsetMin = new Vector2(m_FontSize / 2, 0);
                rectTransform.offsetMax = new Vector2(-(m_FontSize / 2), 0);
                m_TitleText = titleTextGo.GetComponent<Text>();
                m_TitleText.font = m_Font;
                m_TitleText.fontSize = m_FontSize;
                m_TitleText.alignment = TextAnchor.MiddleLeft;
                m_TitleText.color = m_TextColor;
                m_TitleText.text = "配置文件列表";

                //配置文件列表操作按钮栏
                {
                    m_FileListButtonGO = new GameObject("_FileListButtonBar_", typeof(CanvasRenderer), typeof(RawImage), typeof(HorizontalLayoutGroup));
                    m_FileListButtonGO.transform.SetParent(m_TopBarGO.transform, false);
                    m_FileListButtonGO.GetComponent<RectTransform>().anchorMin = Vector2.zero;
                    m_FileListButtonGO.GetComponent<RectTransform>().anchorMax = Vector2.one;
                    m_FileListButtonGO.GetComponent<RectTransform>().offsetMin = new Vector2(m_FontSize / 2, 0);
                    m_FileListButtonGO.GetComponent<RectTransform>().offsetMax = new Vector2(-(m_FontSize / 2), 0);
                    m_FileListButtonGO.GetComponent<RawImage>().color = Color.clear;
                    m_FileListButtonGO.GetComponent<HorizontalLayoutGroup>().childControlWidth = false;
                    m_FileListButtonGO.GetComponent<HorizontalLayoutGroup>().childControlHeight = false;
                    m_FileListButtonGO.GetComponent<HorizontalLayoutGroup>().childForceExpandWidth = false;
                    m_FileListButtonGO.GetComponent<HorizontalLayoutGroup>().childForceExpandHeight = false;
                    m_FileListButtonGO.GetComponent<HorizontalLayoutGroup>().childAlignment = TextAnchor.MiddleRight;
                    m_FileListButtonGO.GetComponent<HorizontalLayoutGroup>().spacing = m_FontSize;

                    GameObject buttonGO = new GameObject("_NewFileButton_", typeof(CanvasRenderer), typeof(RawImage), typeof(Button));
                    buttonGO.transform.SetParent(m_FileListButtonGO.transform, false);
                    rectTransform = buttonGO.transform as RectTransform;
                    rectTransform.sizeDelta = new Vector2(m_FontSize * 5, m_FontSize * 1.6f);
                    buttonGO.GetComponent<Button>().onClick.AddListener(NewFileButton);
                    buttonGO.GetComponent<RawImage>().color = m_ButtonBackgroundColor;
                    GameObject buttonTextGO = new GameObject("_Text_", typeof(CanvasRenderer), typeof(Text));
                    buttonTextGO.transform.SetParent(buttonGO.transform, false);
                    Text text = buttonTextGO.GetComponent<Text>();
                    text.font = m_Font;
                    text.fontSize = m_FontSize;
                    text.alignment = TextAnchor.MiddleCenter;
                    text.color = m_TextColor;
                    text.text = "新建文件";
                    rectTransform = buttonTextGO.transform as RectTransform;
                    rectTransform.anchorMin = new Vector2(0, 0);
                    rectTransform.anchorMax = new Vector2(1, 1);
                    rectTransform.offsetMin = new Vector2(0, 0);
                    rectTransform.offsetMax = new Vector2(0, 0);

                    buttonGO = new GameObject("_SaveAllButton_", typeof(CanvasRenderer), typeof(RawImage), typeof(Button));
                    buttonGO.transform.SetParent(m_FileListButtonGO.transform, false);
                    rectTransform = buttonGO.transform as RectTransform;
                    rectTransform.sizeDelta = new Vector2(m_FontSize * 5, m_FontSize * 1.6f);
                    buttonGO.GetComponent<Button>().onClick.AddListener(SaveAllButton);
                    buttonGO.GetComponent<RawImage>().color = m_ButtonBackgroundColor;
                    buttonTextGO = new GameObject("_Text_", typeof(CanvasRenderer), typeof(Text));
                    buttonTextGO.transform.SetParent(buttonGO.transform, false);
                    text = buttonTextGO.GetComponent<Text>();
                    text.font = m_Font;
                    text.fontSize = m_FontSize;
                    text.alignment = TextAnchor.MiddleCenter;
                    text.color = m_TextColor;
                    text.text = "保存全部";
                    rectTransform = buttonTextGO.transform as RectTransform;
                    rectTransform.anchorMin = new Vector2(0, 0);
                    rectTransform.anchorMax = new Vector2(1, 1);
                    rectTransform.offsetMin = new Vector2(0, 0);
                    rectTransform.offsetMax = new Vector2(0, 0);

                    buttonGO = new GameObject("_CloseButton_", typeof(CanvasRenderer), typeof(RawImage), typeof(Button));
                    buttonGO.transform.SetParent(m_FileListButtonGO.transform, false);
                    rectTransform = buttonGO.transform as RectTransform;
                    rectTransform.sizeDelta = new Vector2(m_FontSize * 4, m_FontSize * 1.6f);
                    buttonGO.GetComponent<Button>().onClick.AddListener(CloseButton);
                    buttonGO.GetComponent<RawImage>().color = m_ButtonBackgroundColor;
                    buttonTextGO = new GameObject("_Text_", typeof(CanvasRenderer), typeof(Text));
                    buttonTextGO.transform.SetParent(buttonGO.transform, false);
                    text = buttonTextGO.GetComponent<Text>();
                    text.font = m_Font;
                    text.fontSize = m_FontSize;
                    text.alignment = TextAnchor.MiddleCenter;
                    text.color = m_TextColor;
                    text.text = "关闭";
                    rectTransform = buttonTextGO.transform as RectTransform;
                    rectTransform.anchorMin = new Vector2(0, 0);
                    rectTransform.anchorMax = new Vector2(1, 1);
                    rectTransform.offsetMin = new Vector2(0, 0);
                    rectTransform.offsetMax = new Vector2(0, 0);
                }

                //配置项列表操作按钮栏
                {
                    m_LineListButtonGO = new GameObject("_LineListButtonBar_", typeof(CanvasRenderer), typeof(RawImage), typeof(HorizontalLayoutGroup));
                    m_LineListButtonGO.transform.SetParent(m_TopBarGO.transform, false);
                    rectTransform = m_LineListButtonGO.transform as RectTransform;
                    rectTransform.anchorMin = Vector2.zero;
                    rectTransform.anchorMax = Vector2.one;
                    rectTransform.offsetMin = new Vector2(m_FontSize / 2, 0);
                    rectTransform.offsetMax = new Vector2(-(m_FontSize / 2), 0);
                    m_LineListButtonGO.GetComponent<RawImage>().color = Color.clear;
                    m_LineListButtonGO.GetComponent<HorizontalLayoutGroup>().childControlWidth = false;
                    m_LineListButtonGO.GetComponent<HorizontalLayoutGroup>().childControlHeight = false;
                    m_LineListButtonGO.GetComponent<HorizontalLayoutGroup>().childForceExpandWidth = false;
                    m_LineListButtonGO.GetComponent<HorizontalLayoutGroup>().childForceExpandHeight = false;
                    m_LineListButtonGO.GetComponent<HorizontalLayoutGroup>().childAlignment = TextAnchor.MiddleRight;
                    m_LineListButtonGO.GetComponent<HorizontalLayoutGroup>().spacing = m_FontSize;

                    GameObject buttonGo = new GameObject("_AddItemButton_", typeof(CanvasRenderer), typeof(RawImage), typeof(Button));
                    buttonGo.transform.SetParent(m_LineListButtonGO.transform, false);
                    rectTransform = buttonGo.transform as RectTransform;
                    rectTransform.sizeDelta = new Vector2(m_FontSize * 4, m_FontSize * 1.6f);
                    buttonGo.GetComponent<Button>().onClick.AddListener(AddLineButton);
                    buttonGo.GetComponent<RawImage>().color = m_ButtonBackgroundColor;
                    GameObject buttonText = new GameObject("_Text_", typeof(CanvasRenderer), typeof(Text));
                    buttonText.transform.SetParent(buttonGo.transform, false);
                    Text text = buttonText.GetComponent<Text>();
                    text.font = m_Font;
                    text.fontSize = m_FontSize;
                    text.alignment = TextAnchor.MiddleCenter;
                    text.color = m_TextColor;
                    text.text = "新建项";
                    rectTransform = buttonText.transform as RectTransform;
                    rectTransform.anchorMin = new Vector2(0, 0);
                    rectTransform.anchorMax = new Vector2(1, 1);
                    rectTransform.offsetMin = new Vector2(0, 0);
                    rectTransform.offsetMax = new Vector2(0, 0);

                    buttonGo = new GameObject("_SaveButton_", typeof(CanvasRenderer), typeof(RawImage), typeof(Button));
                    buttonGo.transform.SetParent(m_LineListButtonGO.transform, false);
                    rectTransform = buttonGo.transform as RectTransform;
                    rectTransform.sizeDelta = new Vector2(m_FontSize * 4, m_FontSize * 1.6f);
                    buttonGo.GetComponent<Button>().onClick.AddListener(SaveButton);
                    buttonGo.GetComponent<RawImage>().color = m_ButtonBackgroundColor;
                    buttonText = new GameObject("_Text_", typeof(CanvasRenderer), typeof(Text));
                    buttonText.transform.SetParent(buttonGo.transform, false);
                    text = buttonText.GetComponent<Text>();
                    text.font = m_Font;
                    text.fontSize = m_FontSize;
                    text.alignment = TextAnchor.MiddleCenter;
                    text.color = m_TextColor;
                    text.text = "保存";
                    rectTransform = buttonText.transform as RectTransform;
                    rectTransform.anchorMin = new Vector2(0, 0);
                    rectTransform.anchorMax = new Vector2(1, 1);
                    rectTransform.offsetMin = new Vector2(0, 0);
                    rectTransform.offsetMax = new Vector2(0, 0);

                    buttonGo = new GameObject("_BackButton_", typeof(CanvasRenderer), typeof(RawImage), typeof(Button));
                    buttonGo.transform.SetParent(m_LineListButtonGO.transform, false);
                    rectTransform = buttonGo.transform as RectTransform;
                    rectTransform.sizeDelta = new Vector2(m_FontSize * 4, m_FontSize * 1.6f);
                    buttonGo.GetComponent<Button>().onClick.AddListener(BackButton);
                    buttonGo.GetComponent<RawImage>().color = m_ButtonBackgroundColor;
                    buttonText = new GameObject("_Text_", typeof(CanvasRenderer), typeof(Text));
                    buttonText.transform.SetParent(buttonGo.transform, false);
                    text = buttonText.GetComponent<Text>();
                    text.font = m_Font;
                    text.fontSize = m_FontSize;
                    text.alignment = TextAnchor.MiddleCenter;
                    text.color = m_TextColor;
                    text.text = "返回";
                    rectTransform = buttonText.transform as RectTransform;
                    rectTransform.anchorMin = new Vector2(0, 0);
                    rectTransform.anchorMax = new Vector2(1, 1);
                    rectTransform.offsetMin = new Vector2(0, 0);
                    rectTransform.offsetMax = new Vector2(0, 0);
                }
            }

            //中间栏内容部分
            {
                m_ContentBarGO = new GameObject("_ContentBar_", typeof(CanvasRenderer), typeof(RawImage), typeof(ScrollRect));
                m_ContentBarGO.transform.SetParent(m_WindowGO.transform, false);
                m_ContentBarGO.GetComponent<RawImage>().color = m_BarBackgroundColor;
                rectTransform = m_ContentBarGO.transform as RectTransform;
                rectTransform.anchorMin = Vector2.zero;
                rectTransform.anchorMax = Vector2.one;
                rectTransform.offsetMin = new Vector2(m_FontSize / 2, m_FontSize / 2);
                rectTransform.offsetMax = new Vector2(-(m_FontSize / 2), -((m_FontSize / 2) + (m_FontSize * 2) + (m_FontSize / 4)));
                m_ContentScrollRect = m_ContentBarGO.GetComponent<ScrollRect>();
                m_ContentScrollRect.movementType = ScrollRect.MovementType.Clamped;
                m_ContentScrollRect.scrollSensitivity = 50;
                m_ContentScrollRect.horizontal = false;
                m_ContentScrollRect.vertical = true;

                GameObject LogViewport = new GameObject("_Viewport_", typeof(CanvasRenderer), typeof(RawImage), typeof(Mask));
                LogViewport.transform.SetParent(m_ContentBarGO.transform, false);
                LogViewport.GetComponent<Mask>().showMaskGraphic = false;
                rectTransform = LogViewport.transform as RectTransform;
                rectTransform.anchorMin = Vector2.zero;
                rectTransform.anchorMax = Vector2.one;
                rectTransform.offsetMin = Vector2.zero;
                rectTransform.offsetMax = Vector2.zero;

                m_ContentScrollRect.viewport = rectTransform;

                m_ContentGO = new GameObject("_Content_");
                m_ContentGO.transform.SetParent(LogViewport.transform, false);
                VerticalLayoutGroup verticalLayoutGroup = m_ContentGO.AddComponent<VerticalLayoutGroup>();
                verticalLayoutGroup.childControlWidth = true;
                verticalLayoutGroup.childControlHeight = false;
                verticalLayoutGroup.childForceExpandWidth = true;
                verticalLayoutGroup.childForceExpandHeight = false;
                verticalLayoutGroup.padding = new RectOffset(m_FontSize / 2, m_FontSize / 2, m_FontSize / 2, m_FontSize / 2);
                verticalLayoutGroup.spacing = m_FontSize / 2;
                ContentSizeFitter contentSizeFitter = m_ContentGO.AddComponent<ContentSizeFitter>();
                contentSizeFitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
                contentSizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
                rectTransform = m_ContentGO.transform as RectTransform;
                rectTransform.pivot = new Vector2(0, 1);
                rectTransform.anchorMin = new Vector2(0, 1);
                rectTransform.anchorMax = new Vector2(1, 1);
                rectTransform.offsetMin = Vector2.zero;
                rectTransform.offsetMax = Vector2.zero;

                m_ContentScrollRect.content = rectTransform;

                GameObject scrollbarVerticalGO = new GameObject("_ScrollbarVertical_");
                scrollbarVerticalGO.transform.SetParent(m_ContentBarGO.transform, false);
                scrollbarVerticalGO.AddComponent<CanvasRenderer>();
                RawImage image = scrollbarVerticalGO.AddComponent<RawImage>();
                image.color = m_ScrollbarBackgroundColor;
                Scrollbar scrollbar = scrollbarVerticalGO.AddComponent<Scrollbar>();
                scrollbar.direction = Scrollbar.Direction.BottomToTop;
                rectTransform = scrollbarVerticalGO.transform as RectTransform;
                rectTransform.pivot = new Vector2(1, 1);
                rectTransform.anchorMin = new Vector2(1, 0);
                rectTransform.anchorMax = new Vector2(1, 1);
                rectTransform.offsetMin = new Vector2(-(m_FontSize / 2), 0);
                rectTransform.offsetMax = new Vector2(0, 0);

                GameObject scrollbarHandleGO = new GameObject("_Handle_");
                scrollbarHandleGO.transform.SetParent(scrollbarVerticalGO.transform, false);
                scrollbarHandleGO.AddComponent<CanvasRenderer>();
                image = scrollbarHandleGO.AddComponent<RawImage>();
                image.color = m_ScrollbarForegroundColor;
                rectTransform = scrollbarHandleGO.transform as RectTransform;
                rectTransform.anchorMin = new Vector2(0, 0);
                rectTransform.anchorMax = new Vector2(1, 1);
                rectTransform.offsetMin = new Vector2(0, 0);
                rectTransform.offsetMax = new Vector2(0, 0);

                scrollbar.targetGraphic = image;
                scrollbar.handleRect = rectTransform;

                m_ContentScrollRect.verticalScrollbar = scrollbar;
                m_ContentScrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport;
            }
        }
        private void Start()
        {
            m_FileListButtonGO.SetActive(true);
            m_LineListButtonGO.SetActive(false);
            UpdateFileShowList();
        }
        private void UpdateFileShowList()
        {
            foreach (var item in m_ItemGameObjects)
            {
                Destroy(item);
            }
            m_ItemGameObjects.Clear();
            foreach (var item in Config.configFiles)
            {
                GameObject buttonGO = new GameObject("_Item_", typeof(CanvasRenderer), typeof(RawImage), typeof(Button));
                buttonGO.transform.SetParent(m_ContentGO.transform);
                RectTransform rectTransform = buttonGO.transform as RectTransform;
                rectTransform.sizeDelta = new Vector2(m_FontSize * 4, m_FontSize * 1.6f);
                buttonGO.GetComponent<Button>().onClick.ExAddListener(SelectConfigFile, item);
                buttonGO.GetComponent<RawImage>().color = m_ButtonBackgroundColor;
                GameObject buttonTextGO = new GameObject("_Text_", typeof(CanvasRenderer), typeof(Text));
                buttonTextGO.transform.SetParent(buttonGO.transform, false);
                Text text = buttonTextGO.GetComponent<Text>();
                text.font = m_Font;
                text.fontSize = m_FontSize;
                text.alignment = TextAnchor.MiddleLeft;
                text.color = m_TextColor;
                text.text = item.path;
                rectTransform = buttonTextGO.transform as RectTransform;
                rectTransform.anchorMin = new Vector2(0, 0);
                rectTransform.anchorMax = new Vector2(1, 1);
                rectTransform.offsetMin = new Vector2(0, 0);
                rectTransform.offsetMax = new Vector2(0, 0);
                m_ItemGameObjects.Add(buttonGO);
            }
        }
        private void UpdateLineShowList()
        {
            foreach (var item in m_ItemGameObjects)
            {
                Destroy(item);
            }
            m_ItemGameObjects.Clear();
            foreach (var line in m_CurrentConfigFile.lines)
            {
                if (line.name == null)
                {
                    continue;
                }
                AddLine(line.name, line.value, line.comment);
            }
        }
        private void AddLine(string name, string value, string comment)
        {
            GameObject LineGo = new GameObject("_Item_", typeof(CanvasRenderer), typeof(RawImage));
            LineGo.transform.SetParent(m_ContentGO.transform);
            RectTransform rectTransform = LineGo.transform as RectTransform;
            rectTransform.sizeDelta = new Vector2(m_FontSize * 4, m_FontSize * 1.6f);
            LineGo.GetComponent<RawImage>().color = Color.clear;

            GameObject inputFieldGO = new GameObject("_NameInputField_");
            inputFieldGO.transform.SetParent(LineGo.transform, false);
            inputFieldGO.AddComponent<CanvasRenderer>();
            inputFieldGO.AddComponent<FocusedHandler>();
            RawImage image = inputFieldGO.AddComponent<RawImage>();
            image.color = m_ButtonBackgroundColor;
            InputField inputField = inputFieldGO.AddComponent<InputField>();
            inputField.characterLimit = 256;
            rectTransform = inputFieldGO.transform as RectTransform;
            rectTransform.anchorMin = new Vector2(0, 0);
            rectTransform.anchorMax = new Vector2(0.2f, 1);
            rectTransform.offsetMin = new Vector2(0, 0);
            rectTransform.offsetMax = new Vector2(-m_FontSize / 2, 0);
            GameObject placeholderGO = new GameObject("_Placeholder_");
            placeholderGO.transform.SetParent(inputFieldGO.transform, false);
            placeholderGO.AddComponent<CanvasRenderer>();
            Text text = placeholderGO.AddComponent<Text>();
            text.font = m_Font;
            text.fontSize = m_FontSize;
            text.color = m_TextColor * 0.5f;
            text.alignment = TextAnchor.MiddleLeft;
            text.fontStyle = FontStyle.Italic;
            text.text = "名字";
            rectTransform = placeholderGO.transform as RectTransform;
            rectTransform.anchorMin = Vector2.zero;
            rectTransform.anchorMax = Vector2.one;
            rectTransform.offsetMin = new Vector2(m_FontSize / 2, 0);
            rectTransform.offsetMax = new Vector2(-m_FontSize / 2, 0);
            inputField.placeholder = text;
            GameObject inputTextGO = new GameObject("_InputText_");
            inputTextGO.transform.SetParent(inputFieldGO.transform, false);
            inputTextGO.AddComponent<CanvasRenderer>();
            text = inputTextGO.AddComponent<Text>();
            text.font = m_Font;
            text.fontSize = m_FontSize;
            text.color = m_TextColor;
            text.alignment = TextAnchor.MiddleLeft;
            text.supportRichText = false;
            rectTransform = inputTextGO.transform as RectTransform;
            rectTransform.anchorMin = Vector2.zero;
            rectTransform.anchorMax = Vector2.one;
            rectTransform.offsetMin = new Vector2(m_FontSize / 2, 0);
            rectTransform.offsetMax = new Vector2(-m_FontSize / 2, 0);
            inputField.textComponent = text;
            inputField.text = name;

            inputFieldGO = new GameObject("_ValueInputField_");
            inputFieldGO.transform.SetParent(LineGo.transform, false);
            inputFieldGO.AddComponent<CanvasRenderer>();
            inputFieldGO.AddComponent<FocusedHandler>();
            image = inputFieldGO.AddComponent<RawImage>();
            image.color = m_ButtonBackgroundColor;
            inputField = inputFieldGO.AddComponent<InputField>();
            inputField.characterLimit = 256;
            rectTransform = inputFieldGO.transform as RectTransform;
            rectTransform.anchorMin = new Vector2(0.2f, 0);
            rectTransform.anchorMax = new Vector2(0.5f, 1);
            rectTransform.offsetMin = new Vector2(0, 0);
            rectTransform.offsetMax = new Vector2(-m_FontSize / 2, 0);
            placeholderGO = new GameObject("_Placeholder_");
            placeholderGO.transform.SetParent(inputFieldGO.transform, false);
            placeholderGO.AddComponent<CanvasRenderer>();
            text = placeholderGO.AddComponent<Text>();
            text.font = m_Font;
            text.fontSize = m_FontSize;
            text.color = m_TextColor * 0.5f;
            text.alignment = TextAnchor.MiddleLeft;
            text.fontStyle = FontStyle.Italic;
            text.text = "值";
            rectTransform = placeholderGO.transform as RectTransform;
            rectTransform.anchorMin = Vector2.zero;
            rectTransform.anchorMax = Vector2.one;
            rectTransform.offsetMin = new Vector2(m_FontSize / 2, 0);
            rectTransform.offsetMax = new Vector2(-m_FontSize / 2, 0);
            inputField.placeholder = text;
            inputTextGO = new GameObject("_InputText_");
            inputTextGO.transform.SetParent(inputFieldGO.transform, false);
            inputTextGO.AddComponent<CanvasRenderer>();
            text = inputTextGO.AddComponent<Text>();
            text.font = m_Font;
            text.fontSize = m_FontSize;
            text.color = m_TextColor;
            text.alignment = TextAnchor.MiddleLeft;
            text.supportRichText = false;
            rectTransform = inputTextGO.transform as RectTransform;
            rectTransform.anchorMin = Vector2.zero;
            rectTransform.anchorMax = Vector2.one;
            rectTransform.offsetMin = new Vector2(m_FontSize / 2, 0);
            rectTransform.offsetMax = new Vector2(-m_FontSize / 2, 0);
            inputField.textComponent = text;
            inputField.text = value;

            inputFieldGO = new GameObject("_CommentInputField_");
            inputFieldGO.transform.SetParent(LineGo.transform, false);
            inputFieldGO.AddComponent<CanvasRenderer>();
            inputFieldGO.AddComponent<FocusedHandler>();
            image = inputFieldGO.AddComponent<RawImage>();
            image.color = m_ButtonBackgroundColor;
            inputField = inputFieldGO.AddComponent<InputField>();
            inputField.characterLimit = 256;
            rectTransform = inputFieldGO.transform as RectTransform;
            rectTransform.anchorMin = new Vector2(0.5f, 0);
            rectTransform.anchorMax = new Vector2(1, 1);
            rectTransform.offsetMin = new Vector2(0, 0);
            rectTransform.offsetMax = new Vector2(0, 0);
            placeholderGO = new GameObject("_Placeholder_");
            placeholderGO.transform.SetParent(inputFieldGO.transform, false);
            placeholderGO.AddComponent<CanvasRenderer>();
            text = placeholderGO.AddComponent<Text>();
            text.font = m_Font;
            text.fontSize = m_FontSize;
            text.color = m_TextColor * 0.5f;
            text.alignment = TextAnchor.MiddleLeft;
            text.fontStyle = FontStyle.Italic;
            text.text = "注释说明";
            rectTransform = placeholderGO.transform as RectTransform;
            rectTransform.anchorMin = Vector2.zero;
            rectTransform.anchorMax = Vector2.one;
            rectTransform.offsetMin = new Vector2(m_FontSize / 2, 0);
            rectTransform.offsetMax = new Vector2(-m_FontSize / 2, 0);
            inputField.placeholder = text;
            inputTextGO = new GameObject("_InputText_");
            inputTextGO.transform.SetParent(inputFieldGO.transform, false);
            inputTextGO.AddComponent<CanvasRenderer>();
            text = inputTextGO.AddComponent<Text>();
            text.font = m_Font;
            text.fontSize = m_FontSize;
            text.color = Color.green;
            text.alignment = TextAnchor.MiddleLeft;
            text.supportRichText = false;
            rectTransform = inputTextGO.transform as RectTransform;
            rectTransform.anchorMin = Vector2.zero;
            rectTransform.anchorMax = Vector2.one;
            rectTransform.offsetMin = new Vector2(m_FontSize / 2, 0);
            rectTransform.offsetMax = new Vector2(-m_FontSize / 2, 0);
            inputField.textComponent = text;
            inputField.text = comment;

            m_ItemGameObjects.Add(LineGo);
        }
        private void SelectConfigFile(ConfigFile configFile)
        {
            m_CurrentConfigFile = configFile;
            m_TitleText.text = configFile.path;
            m_FileListButtonGO.SetActive(false);
            m_LineListButtonGO.SetActive(true);
            UpdateLineShowList();
        }
        private void BackButton()
        {
            m_TitleText.text = "配置文件列表";
            m_FileListButtonGO.SetActive(true);
            m_LineListButtonGO.SetActive(false);
            UpdateFileShowList();
        }
        private void SaveAllButton()
        {
            Config.SaveAllConfigFile();
            Notification.Show("保存全部配置文件成功", new NotificationStyle(m_ButtonBackgroundColor * 1.5f, m_TextColor, Color.green));
        }
        private void NewFileButton()
        {
#if UNITY_EDITOR
            string path = UnityEditor.EditorUtility.SaveFilePanel("保存路径", lastSaveDirectory == null ? Application.dataPath : lastSaveDirectory, "NewConfig", "ini");
            if (path == null || path.Length == 0) return;
            lastSaveDirectory = System.IO.Path.GetDirectoryName(path);

            ConfigFile configFile = Config.CreateFile(path);
            SelectConfigFile(configFile);
            if (configFile.count == 0)
            {
                AddLineButton();
            }
#endif
        }
        private void AddLineButton()
        {
            if (m_CurrentConfigFile == null)
                return;

            string name = "新建项";
            for (int i = 0; i < 1000; i++)
            {
                bool isExists = false;
                foreach (var item in m_ItemGameObjects)
                {
                    if (item.transform.Find("_NameInputField_").GetComponent<InputField>().text == name)
                    {
                        isExists = true;
                        break;
                    }
                }
                if (isExists)
                    name = "新建项" + i;
                else
                    break;
            }

            AddLine(name, "新建值", "");

            LayoutRebuilder.ForceRebuildLayoutImmediate(m_ContentGO.GetComponent<RectTransform>());
            m_ContentScrollRect.normalizedPosition = Vector2.zero;

            m_ItemGameObjects[m_ItemGameObjects.Count - 1].transform.Find("_NameInputField_").GetComponent<InputField>().Select();
        }
        private void SaveButton()
        {
            if (m_CurrentConfigFile == null)
                return;

            //m_CurrentConfigFile.Clear();
            foreach (var item in m_ItemGameObjects)
            {
                string name = item.transform.Find("_NameInputField_").GetComponent<InputField>().text.Trim();
                if (name.Length == 0) continue;

                string value = item.transform.Find("_ValueInputField_").GetComponent<InputField>().text.Trim();

                string comment = item.transform.Find("_CommentInputField_").GetComponent<InputField>().text;
                if (comment.Length == 0) comment = null;

                m_CurrentConfigFile.Set(name, value, comment);
            }
            m_CurrentConfigFile.Save();

            Config.NotifyReload(m_CurrentConfigFile);

            Notification.Show("保存当前配置文件成功", new NotificationStyle(m_ButtonBackgroundColor * 1.5f, m_TextColor, Color.green));
        }
        private void CloseButton()
        {
            Destroy(gameObject);
        }
    }
}